﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Enter.Mvc.Base.Skinning
{
	public class UnityViewEngine : BuildManagerViewEngine
	{
		private static string[] FileExtension = new string[] { "cshtml", "vbhtml" };
		private readonly static HashSet<string> hs = new HashSet<string>(FileExtension);

		public UnityViewEngine(ISkinEngine skinEngine)
		{
			SkinEngine = skinEngine;
			base.FileExtensions = FileExtension;
		}

		public string SkinName { get; set; }
		public ISkinEngine SkinEngine { get; private set; }

		protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
		{
			MyChyViewType viewtype = CheckMyChyViewType(partialPath);
			switch (viewtype)
			{
				case MyChyViewType.Razor:
					return new RazorView(controllerContext, partialPath, null, false, base.FileExtensions);
				//break;
				case MyChyViewType.From:
					return new WebFormView(controllerContext, partialPath);
				//break;
				default:
					return new RazorView(controllerContext, partialPath, null, false, base.FileExtensions);
				//break;
			}

		}

		protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
		{
			switch (CheckMyChyViewType(viewPath))
			{
				case MyChyViewType.Razor:
					return new RazorView(controllerContext, viewPath, masterPath, false, base.FileExtensions);
				//break;
				case MyChyViewType.From:
					return new WebFormView(controllerContext, viewPath, masterPath);
				//break;
				default:
					return new RazorView(controllerContext, viewPath, masterPath, false, base.FileExtensions);
				//break;
			}
		}

		public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
		{
			if (controllerContext == null)
			{
				throw new ArgumentNullException("controllerContext");
			}

			if (string.IsNullOrEmpty(partialViewName))
			{
				throw new ArgumentNullException("partialViewName");
			}

			string controllerName = controllerContext.RouteData.GetRequiredString("controller");

			string[] locationsSearched;
			string partialPath = SkinEngine.FindPartialViewPath(partialViewName, controllerName, out locationsSearched);

			return !string.IsNullOrEmpty(partialPath)
					   ? new ViewEngineResult(CreatePartialView(controllerContext, partialPath), this)
					   : new ViewEngineResult(locationsSearched);
		}

		public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
		{
			if (controllerContext == null)
			{
				throw new ArgumentNullException("controllerContext");
			}

			if (string.IsNullOrEmpty(viewName))
			{
				throw new ArgumentNullException("viewName");
			}

			string controllerName = controllerContext.RouteData.GetRequiredString("controller");

			string[] viewLocationsSearched;
			string viewPath = SkinEngine.FindViewPath(viewName, controllerName, out viewLocationsSearched);

			if (string.IsNullOrEmpty(viewPath))
			{
				return new ViewEngineResult(viewLocationsSearched);
			}
			string masterPath = string.Empty;
			if (masterName.Length > 0)
			{
				string[] masterLocationsSearched;
				masterPath = SkinEngine.FindMasterPath(masterName, controllerName, out masterLocationsSearched);

				if (!string.IsNullOrEmpty(masterName) && string.IsNullOrEmpty(masterPath))
				{
					return new ViewEngineResult(masterLocationsSearched);
				}
			}
			return new ViewEngineResult(CreateView(controllerContext, viewPath, masterPath), this);
		}

		public override void ReleaseView(ControllerContext controllerContext, IView view)
		{
			IDisposable disposable = view as IDisposable;
			if (disposable != null)
			{
				disposable.Dispose();
			}
		}


		#region 判断是使用Razor 还是使用 From

		private MyChyViewType CheckMyChyViewType(string viewPath)
		{
			string ext = viewPath.Substring(viewPath.LastIndexOf('.') + 1).ToLower();
			if (hs.Contains(ext))
			{
				return MyChyViewType.Razor;
			}
			return MyChyViewType.From;
		}


		#endregion
	}
}
